﻿/*
Copyright (C) 2010 INOUE Hiroyuki

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

using System;
using System.IO;

namespace CodePlex.Dombly.DiskUsage.BusinessLogic
{
    /// <summary>
    /// Provides the base class for both Directory and File classes, which extends System.IO.FileSystemInfo class.
    /// </summary>
    /// <typeparam name="TInfo">Backend System.IO class.</typeparam>
    public abstract class FileSystem<TInfo> : IFileSystem, IParent
        where TInfo: FileSystemInfo
    {
        #region properties

        #region Id
        /// <summary>
        /// Gets the unique identifier of the instance.
        /// </summary>
        public Guid Id { get { return this._Id; } }
        private readonly Guid _Id;
        #endregion

        #region Name
        /// <summary>
        /// For files, gets the name of the file.  For directories, gets 
        /// the name of the last directory in the hierarchy if a hierarchy 
        /// exists.  
        /// Otherwise, the Name property gets the name of the directory.
        /// </summary>
        public string Name { get { return this._Info.Name; } }
        #endregion

        #region FullName
        /// <summary>
        /// Gets the full path of the directory or file.
        /// </summary>
        public string FullName { get { return this._Info.FullName; } }
        #endregion

        #region Parent
        /// <summary>
        /// Gets parent Directory object.
        /// </summary>
        public IDirectory Parent { get { return this._Parent; } }
        #endregion

        #region ParentId
        /// <summary>
        /// Gets the unique identifier of the parent directory.
        /// </summary>
        public Guid? ParentId
        {
            get
            {
                if (this._Parent == null) return null;
                return this._Parent.Id;
            }
        }
        #endregion

        #region Created
        /// <summary>
        /// Gets the creation time of the current file or directory.
        /// </summary>
        public DateTime? Created { get { return this._Info.CreationTime; } }
        #endregion

        #region Updated
        /// <summary>
        /// Gets the time when the current file or directory was last 
        /// written to.
        /// </summary>
        public DateTime? Updated { get { return this._Info.LastWriteTime; } }
        #endregion

        #region SnapShotId
        /// <summary>
        /// Gets the unique identifier of the snapshot.
        /// </summary>
        public Guid SnapShotId { get; private set; }
        #endregion

        #region Scanned
        /// <summary>
        /// Gets or sets the time when the snapshot of the file or 
        /// directory was taken.
        /// </summary>
        public DateTime? Scanned
        {
            get
            {
                return this._Scanned;
            }
            protected set
            {
                this._Scanned = value;
                if (this.ScanCompleted != null)
                    this.ScanCompleted(this, new EventArgs());
            }
        }
        private DateTime? _Scanned;
        #endregion

        #region abstract members
        public abstract int DirectoryCount { get; }
        public abstract int FileCount { get; }
        public abstract long FileSize { get; }
        public abstract string Owner { get; }
        #endregion

        #endregion

        #region variables

        /// <summary>
        /// The backend System.IO.FileSystemInfo derived instance.
        /// </summary>
        protected readonly TInfo _Info;

        private readonly IDirectory _Parent;

        #endregion

        #region constructors
        /// <summary>
        /// Initializes a new instance of the FileSystem class.
        /// </summary>
        /// <param name="info">
        /// The backend System.IO.FileSystemInfo derived instance.
        /// </param>
        /// <param name="parent">
        /// The Directory instance which represents the parent directory.
        /// </param>
        protected FileSystem(TInfo info, IDirectory parent)
        {
            this._Id = new Guid();
            this._Info = info;
            this._Parent = parent;
        }
        #endregion

        #region events

        /// <summary>
        /// Occurs when the scan of this instance is completed.
        /// </summary>
        public event EventHandler ScanCompleted;

        #endregion
    }
}
